<?php

require_once "bbcode.php";

define('QUERY_START', "SELECT `blog`.`id`, `title`, `body`, `timestamp`, `show`, `users`.`id` AS `user_id`, `users`.`username`, `users`.`display_name` FROM `blog` LEFT JOIN `users` ON `blog`.`author` = `users`.`id` ");

/*
 * Classes Blog and Post rely upon a persistent connection to the MySql server
 */
 
class Post {
	public $id;
	public $title;
	public $timestamp;
	public $user_id;
	public $username;
	public $author;
	public $body;
	public $tags;
	public $show;

	public function addTag( $tag ) {
		if( !in_array( $tag, $this->tags ) ) {
			$query = "SELECT * FROM `tags` WHERE strcmp( `tag_name`, '$tag' ) LIMIT 1;";
			$res = mysql_query( $query );
			$count = mysql_num_rows( $res );

			if( $count == 1 ) {
				$row = mysql_fetch_assoc( $res );
				$tag_id = $row[ 'tag_id' ];
			} else {
				$query = "INSERT INTO `tags` ( `tag_name` ) VALUES ( '$tag' );";
				mysql_query( $query );
				if( mysql_affected_rows() == 1 ) {
					$tag_id = mysql_insert_id();
				} else {
					echo 'no rows affected';
					return;
				}
			}

			$query = "INSERT INTO `tag_map` ( `tag_id`, `post_id` ) VALUES ( $tag_id, {$this->id} );";
			mysql_query( $query );
			
			return mysql_affected_rows() == 1;
		}
	}

	public function removeTag( $tag ) {
		if( in_array( $tag, $this->tags ) ) {
			$query = "DELETE FROM `tag_map` WHERE `post_id` = $id AND `tag_id` = ";
			//mysql_query( $query );
		}
	}

	public function clearTags() {
		$this->tags = array();

		$query = "DELETE FROM `tag_map` WHERE `post_id` = {$this->id}";
		mysql_query( $query );
	}

	public function setTags( $tag_csv ) {
		clearTags();

		$tags = explode( $tag_csv );
			
		foreach( $tags as $tag ) {
			$tag = mysql_real_escape_string( trim( $tag ) );
			$res = mysql_query( "SELECT `tag_id` FROM `tags` WHERE strcmp( `tag_name` = '$tag' ) LIMIT 1;" );
			if( mysql_num_rows( $res ) == 1 ) {
				$row = mysql_fetch_assoc( $res );
				$tag_sql[] = "( {$row[ 'tag_id' ]}, {$this->id} )";
			}
		}
		
		$query = "INSERT INTO `tag_map` ( `tag_id`, `post_id` ) VALUES " . implode( ', ', $tag_sql ) . ";";
		mysql_query( $query );
	}

	private function getTags() {
		$this->tags = array();

		$query = "SELECT `tag_name` FROM `tags` INNER JOIN `tag_map` ON `tags`.`tag_id` = `tag_map`.`tag_id` INNER JOIN `blog` ON `tag_map`.`post_id` = `blog`.`id` WHERE `blog`.`id` = {$this->id};";

		$res = mysql_query( $query );
		$count = mysql_num_rows( $res );

		for( $i = 0; $i < $count; ++$i ) {
			$row = mysql_fetch_assoc( $res );
			$this->tags[] = $row[ 'tag_name' ];
		}
	}
	
	public function makeTagLinks( $baseUrl ) {
		if( !is_array( $this->tags ) ) {
			getTags();
		}
		
		foreach( $this->tags as $tag ) {
			$output[] = "<a href=\"$baseUrl?tag=$tag\">$tag</a>";
		}
		
		return count( $output ) ? implode( ', ', $output ) : "none";
	}
	
	public function makeAuthorLink( $baseUrl ) {
		return "<a href=\"$baseUrl?author={$this->username}\">{$this->author}</a>";
	}

	public function makeCommentsLink( $baseUrl ) {
		return "<a href=\"$baseUrl?id={$this->id}\">{$this->author}</a>";
	}
	
	public function formatTimestamp( $format ) {
		return date( $format, $this->timestamp );
	}

	public function getBody( $concise = false, $bbcode = true ) {
		$text = htmlspecialchars( $this->body, ENT_QUOTES, 'UTF-8', false );
		$text = preg_replace( "/[\\r\\n]+/", "</p><p>", $text );
		return "<p>" . $text . "</p>";
//		return $bbcode ? BBCode( $this->body ) : nl2br( $this->body );
	}

	public static function fromArray( $data ) {
		if( !is_array( $data ) ) return false;

		$post = new Post();

		$post->id = $data[ 'id' ];
		$post->title = $data[ 'title' ];
		$post->user_id = $data[ 'user_id' ];
		$post->username = $data[ 'username' ];
		$post->author = $data[ 'display_name' ];
		$post->body = $data[ 'body' ];
		$post->timestamp = $data[ 'timestamp' ];
		$post->show = $data[ 'show' ] == '1' ? true : false;

		if( is_array( $data[ 'tags' ] ) ) $post->tags = $data[ 'tags' ];
		else $post->getTags();

		return $post;
	}
	
	public static function parseTextileLite( $input ) {
//		/\b([_*?-+^~%@]{1})(\w+)\1\b/
//		_italic_
//		*bold*
//		?citation?
//		-deleted text-
//		+inserted text+
//		^superscript^
//		~subscript~
//		%span%
//		@code@
	}
}

class Blog {

	public $showHidden = false;

/*	public __construct() {
		
	} */

	private function showHidden( $query ) {
		return !$showHidden ? $query : "";
	}

	public function getPostById( $id, $visible = true ) {
		$id = mysql_real_escape_string( $id );

		$query = QUERY_START . "WHERE `blog`.`id` = $id" . $this->showHidden( " AND `show` = 1" ) . ";";

		return $this->returnPosts( $query );
	}

	public function getRecentPosts( $offset = 0, $count = 10 ) {
		$offest = mysql_real_escape_string( $offset );
		$count = mysql_real_escape_string( $count );

		$query = QUERY_START . $this->showHidden( "WHERE `show` = 1" ) . " ORDER BY `timestamp` DESC LIMIT $offset, $count;";

		return $this->returnPosts( $query );
	}

	public function getPostsByDateRange( $start, $end ) {
		$start = mysql_real_esacpe_string( $start );
		$end = mysql_real_escape_string( $end );

		$query = QUERY_START . "WHERE " . $this->showHidden( "`show` = 1 AND " ) . "`timestamp` BETWEEN '$start' AND '$end';";

		return $this->returnPosts( $query );
	}

	public function getPostsByAuthor( $author ) {
		$author = mysql_real_escape_string( $author );

		$query = QUERY_START . "WHERE " . $this->showHidden( "`show` = 1 AND " ) . "strcmp( `author`, '$author' ) = 0;";

		return $this->returnPosts( $query );
	}

	public function getPostsByTag( $tag ) {
		$tag = mysql_real_escape_string( $tag );

		$query = QUERY_START . "INNER JOIN `tag_map` ON `blog`.`id` = `tag_map`.`post_id` "
		. "INNER JOIN `tags` ON `tag_map`.`tag_id` = `tags`.`tag_id` WHERE `tags`.`tag_name` = '$tag' "
		. $this->showHidden( " AND `show` = 1" ) . ";";

		return $this->returnPosts( $query );
	}

	public function getPostByTitle( $title ) {
		$title = mysql_real_escape_string( $title );

		$query = QUERY_START . "WHERE " . $this->showHidden( "`show` = 1 AND " ) . "strcmp( `title`, '$title' ) = 0;";

		return $this->returnPosts( $query );
	}

	public function searchPosts( $search ) {
		$search = mysql_real_escape_string( $search );

		$query = QUERY_START . "WHERE " . $this->showHidden( "`show` = 1 AND " ) . "MATCH ( `title`, `author`, `body` ) AGAINST ( '$search' );";

		return $this->returnPosts( $query );
	}
	
	private function returnPosts( $query ) {
		$res = mysql_query( $query );
		$count = mysql_num_rows( $res );

		//echo "<pre>$query\r\n", mysql_errno(), ": ", mysql_error(), "</pre>";

		if( $count == 0 ) $posts = false;
		else if( $count > 0 ) {
			for( $i = 0; $i < $count; ++$i ) {
				$posts[] = Post::fromArray( mysql_fetch_assoc( $res ) );
			}
		}

		return $posts;
	}
	
	public function renderCommentForm() {
		$output  = "<p><input type=\"text\" name=\"comment[name]\" id=\"comment_name\" value=\"\" /><label for=\"comment_name\">Name (required)</label></p>";
		$output .= "<p><input type=\"text\" name=\"comment[email]\" id=\"comment_email\" value=\"\" /><label for=\"comment_name\">Email (required, hidden)</label></p>";
		$output .= "<p><input type=\"text\" name=\"comment[uri]\" id=\"comment_uri\" value=\"\" /><label for=\"comment_name\">URI</label></p>";
		$output .= "<p><textarea rows=\"6\" cols=\"30\" name=\"comment[text]\" id=\"comment_text\" value=\"\" /></p>";
	}

}

?>
